<?php
use Hyperf\Utils\ApplicationContext;
use Psr\SimpleCache\CacheInterface;
use Hyperf\Logger\LoggerFactory;
use Hyperf\Contract\StdoutLoggerInterface;
use Hyperf\HttpServer\Contract\ResponseInterface;
use Hyperf\HttpServer\Contract\RequestInterface;
use Hyperf\Server\ServerFactory;
use Hyperf\Contract\SessionInterface;
use Psr\EventDispatcher\EventDispatcherInterface;
use Hyperf\DbConnection\Db;
use Hyperf\Guzzle\ClientFactory;



if (!function_exists('container')) {
    /**
     * 容器实例
     * @return \Psr\Container\ContainerInterface
     */
    function container()
    {
        return ApplicationContext::getContainer();
    }
}


if (!function_exists('cache')) {
    /**
     * redis 客户端实例
     * @return \Hyperf\Redis\Redis|mixed
     */
    function cache()
    {
        return container()->get(CacheInterface::class);
    }
}


if (!function_exists('logger')) {
    /**
     * 向日志文件记录日志
     * @return \Psr\Log\LoggerInterface
     */
    function logger()
    {
        return container()->get(LoggerFactory::class)->make();
    }
}

if (!function_exists('stdlog')) {
    /**
     * 向控制台输出日志
     * @return StdoutLoggerInterface|mixed
     */
    function stdlog()
    {
        return container()->get(StdoutLoggerInterface::class);
    }
}

if (!function_exists('request')) {
    /**
     * 请求对象
     * @return mixed|RequestInterface
     */
    function request()
    {
        return container()->get(RequestInterface::class);
    }
}

if (!function_exists('response')) {
    /**
     * 请求回应对象
     * @return ResponseInterface|mixed
     */
    function response()
    {
        return container()->get(ResponseInterface::class);
    }
}

if (!function_exists('server')) {
    /**
     * server 实例 基于 swoole server
     * @return \Swoole\Coroutine\Server|\Swoole\Server
     */
    function server()
    {
        return container()->get(ServerFactory::class)->getServer()->getServer();
    }
}

if (!function_exists('session')) {
    /**
     * session 对象
     * @return SessionInterface|mixed
     */
    function session()
    {
        return container()->get(SessionInterface::class);
    }
}


if (!function_exists('event')) {
    /**
     * event 对象
     * @return EventDispatcherInterface|mixed
     */
    function event($event)
    {
        return (container()->get(EventDispatcherInterface::class))->dispatch($event);
    }
}


if (!function_exists('http')) {
    /**
     * curl请求
     * @return bool
     */
    function http($type,$url,$data=[],$options=[])
    {
		$clientFactory = container()->get(ClientFactory::class);
        $client = $clientFactory->create($options);
		$resp = $client->request($type,$url,$data);
        $content = $resp->getBody()->getContents();
		return $content;
    }
}


/**
 * 数据签名认证
 * @param  array  $data 被认证的数据
 * @return string       签名
 */
function data_auth_sign($data,$screct) {
    //数据类型检测
    if(!is_array($data)){
        $data = (array)$data;
    }
    ksort($data); //排序
    $code = http_build_query($data,$screct); //url编码并生成query字符串
    $sign = sha1($code); //生成签名
    return $sign;
}

//对象转数组
function object2array($object) {
	$object = json_decode(json_encode($object),true);
	return $object;
}



function json($data){
	return response()->json($data);
}

//根据键名获取键值
function getItemVal($val,$item_config){
	if(!is_null($val)){
		$str = '';
		foreach(explode(',',$val) as $v){
			foreach(json_decode($item_config,true) as $m){
				if($v == $m['val']){
					$str .= $m['key'].',';
				}
			}
		}
		return rtrim($str,',');
	}
}

//根据键值获取键名
function getValByKey($val,$item_config){
	if($val){
		$str = '';
		foreach(explode(',',$val) as $v){
			foreach(json_decode($item_config,true) as $m){
				if($v == $m['key']){
					$str .= $m['val'].',';
				}
			}
		}
		return rtrim($str,',');
	}
}


//获取键值对信息
function getItemData($data){
	$str = in_array(json_encode(array_values($data)),['[]','[[]]']) ? '' : json_encode(array_values($data),JSON_UNESCAPED_UNICODE);
	return $str;
}

//无限极分类转为带有 children的树形select结构
function _generateSelectTree ($data, $pid = 0) {
	$tree = [];
	if ($data && is_array($data)) {
		foreach($data as $v) {
			if($v['pid'] == $pid) {
				$tree[] = [
					'key' => $v['key'],
					'val' => $v['val'],
					'children' => _generateSelectTree($data, $v['val']),
				];
			}
		}
	}
	return $tree;
}

//无限极分类转为带有 children的树形list表格结构
function _generateListTree ($data, $pid = 0,$config=[]) {
	$tree = [];
	if ($data && is_array($data)) {
		foreach($data as $v) {
			if($v[$config[1]] == $pid) {
				$tree[] = array_merge($v,['children' => _generateListTree($data, $v[$config[0]],$config)]);
			}
		}
	}
	return $tree;
}


//查询格式化
function formatWhere($query,$where){
	foreach($where as $k=>$v){
		if(is_array($v)){
			if($v[1]){
				switch($v[0]){
					case 'like';
						$query = $query->where($k,'like','%'.$v[1].'%');
					break;
					
					case 'in';
						$query = $query->whereIn($k,$v[1]);
					break;
					
					case 'not in';
						$query = $query->whereNotIn($k,$v[1]);
					break;
					
					case 'between';
						$query = $query->whereBetween($k,$v[1]);
					break;
					
					case 'is null';
						$query = $query->whereNull($k);
					break;
					
					case 'not null';
						$query = $query->whereNotNull($k);
					break;
					
					case '<>';
						$query = $query->where($k,'<>',$v[1]);
					break;
					
					case '>';
						$query = $query->where($k,'>',$v[1]);
					break;
					
					case '<';
						$query = $query->where($k,'<',$v[1]);
					break;
					
					case '>=';
						$query = $query->where($k,'>=',$v[1]);
					break;
					
					case '<=';
						$query = $query->where($k,'<=',$v[1]);
					break;
					
					case 'or';
						$query = $query->orWhere($k,$v[2],$v[1]);
					break;
					
					case 'raw';
						$query = $query->whereRaw($v[1]);
					break;
				}
			}
		}else{
			if((string)$v != null){
				$query = $query->where($k,$v);
			}
		}
	}
	return $query;
}


function reaip(){
    $headers = request()->getHeaders();

    if(isset($headers['x-forwarded-for'][0]) && !empty($headers['x-forwarded-for'][0])) {
        return $headers['x-forwarded-for'][0];
    } elseif (isset($headers['x-real-ip'][0]) && !empty($headers['x-real-ip'][0])) {
        return $headers['x-real-ip'][0];
    }

    $serverParams = request()->getServerParams();

    return $serverParams['remote_addr'] ?? '';
}


/**
 * Remove dir.
 * @param $dir
 * @return bool
 */
function remove_dir($dir)
{
    if (is_link($dir) || is_file($dir)) {
        return unlink($dir);
    }
    $files = array_diff(scandir($dir), array('.', '..'));
    foreach ($files as $file) {
        (is_dir("$dir/$file") && !is_link($dir)) ? remove_dir("$dir/$file") : unlink("$dir/$file");
    }
    return rmdir($dir);
}